# https://github.com/pywebio/demos/blob/main/utility_apps/crud_table.py
from pywebio import *
from pywebio.output import *
from pywebio.input import *
from functools import partial
import yaml, os

class CRUDTable():
    '''
    Generalizable Create, Read, Update, Delete Table class.
    :param gen_data_func: custom function that has procedure for generating the table data
    :param edit_func: custom function that edits, requires parameter "i" (index)
    :param del_func: custom function that deletes, requires parameter "i" (index)
    '''

    def __init__(self, gen_data_func, edit_func,filename):

        self.datatable = gen_data_func(filename)
        self.gen_data_func = gen_data_func
        self.edit_func = edit_func
        self.filename = filename


    def put_crud_table(self):
        # the CRUD table without the header
        table = []
        for i, table_row in enumerate(self.datatable):
            # skip the header row
            if i == 0:
                pass
            else:
                # full row of a table
                # get each row element of the data table row
                table_row = [put_text(row_element) for row_element in table_row] + [
                    # use i - 1 here so that it counts after the header row.
                    put_buttons(["◀️"], onclick=partial(self.handle_edit_delete, custom_func=self.edit_func, i=i))

                ]
                table.append(table_row)

        with use_scope("table_scope", clear=True):
            put_table(table,
                      header=self.datatable[0] + ["编辑"]
                      )

    def handle_edit_delete(self, dummy, custom_func, i):
        '''when edit/delete button is pressed, execute the custom edit/delete
        function as well as update CRUD table'''

        # originally had it in the custom functions in step5_filemanager.py,
        # but thought its probably best to have it within the crud_table class to
        # requery all the filepaths and refresh the crud_table

        if custom_func == self.edit_func:
            # if edit function, just do custom_func(i) without confirmation
            self.datatable = custom_func(self.datatable, i)
            # refresh table output

            save_datatable(self.datatable[1:],self.filename)
            self.put_crud_table()


def save_datatable(table,filename):
    print(table)
    dic = dict(zip([i[0] for i in table],[i[1] for i in table]))
    with open(filename, "w",encoding="utf-8") as f:
        yaml.safe_dump(dic, f,allow_unicode=True)

def generate_datatable(filename):
    '''
    custom generate function to use for the CRUD table
    function for generating data.
    index 0 should be the headers.
    '''
    y = yaml.safe_load(open(filename, 'rb'))
    sample_table = [['属性','值']]
    for k, v in y.items():
        # if isinstance(v, list):
        list = [k, v]
        sample_table.append(list)

    return sample_table

def generate_pwstable(filename):
    '''
    custom generate function to use for the CRUD table
    function for generating data.
    index 0 should be the headers.
    '''
    y = yaml.safe_load(open(filename, 'rb'))
    sample_table = [['用户名','密码']]
    for k, v in y.items():
        list = [k, v]
        sample_table.append(list)

    return sample_table

def edit_table(table, i):
    '''
    custom edit function to use for the CRUD table
    load an old blog post, edit it
    '''
    s = input('请为 %s' % (table[i][0]) +'输入新的数据')
    type_func = (int, float, str)
    for f in type_func:
        try:
            table[i][1] = f(s)
            # 因为类型名和函数名一样，就直接返回了
            break
        except ValueError:
            pass
    return table

def yaml_yaw():
    filename = '../../data/config/yawConfig.yaml'
    #put_text("文件名： "+filename)
    growth_table = CRUDTable(gen_data_func=generate_datatable, edit_func=edit_table,filename = filename)
    growth_table.put_crud_table()
def yaml_pitch():
    filename = '../../data/config/pitchConfig.yaml'
    #put_text("文件名： "+filename)
    growth_table = CRUDTable(gen_data_func=generate_datatable, edit_func=edit_table,filename = filename)
    growth_table.put_crud_table()
def yaml_torque():
    filename = '../../data/config/torqueConfig.yaml'
    #put_text("文件名： "+filename)
    growth_table = CRUDTable(gen_data_func=generate_datatable, edit_func=edit_table,filename = filename)
    growth_table.put_crud_table()
def yaml_opcUa():
    filename = '../../data/config/opcUaConfig.yaml'
    # #put_text("文件名： "+filename)
    growth_table = CRUDTable(gen_data_func=generate_datatable, edit_func=edit_table,filename = filename)
    growth_table.put_crud_table()

def yaml_user():
    filename = '../../data/config/userConfig.yaml'
    growth_table = CRUDTable(gen_data_func=generate_pwstable, edit_func=edit_table,filename = filename)
    growth_table.put_crud_table()

if __name__ == '__main__':
    list = [yaml_yaw,yaml_pitch,yaml_torque,yaml_opcUa,yaml_user]
    start_server(list, debug=True, port=9999)